home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / DJGPP2 / CONTRIB / ASPI.ZIP / tape.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-25  |  4.3 KB  |  189 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <dos.h>
  5. #include <sys/farptr.h>
  6. #include <go32.h>
  7.  
  8. #define DOSS _go32_info_block.selector_for_linear_memory
  9.  
  10. #include "aspi.h"
  11. #include "scsidefs.h"
  12. #include "tape.h"
  13.  
  14. #define cstat(x) if (stat < 0) do_cstat(x);
  15.  
  16. static int dat, stat;
  17. static unsigned char cdb[6];
  18. static unsigned long block_size = 20 * 512;
  19.  
  20. static void check_sense(void)
  21. {
  22.   if ((aspi_sense[2] & 0x0f) != KEY_NOSENSE)
  23.   {
  24.     switch (aspi_sense[2] & 0x0f)
  25.     {
  26.       case KEY_NOSENSE:     /*  No Sense */
  27.       case KEY_RECERROR:    /*  Recovered Error */
  28.         return;
  29.       case KEY_NOTREADY:    /*  Not Ready */
  30.         printf("Drive not ready yet.\n");
  31.         exit(0);
  32.       case KEY_DATAPROT:    /*  Data Protect */
  33.         printf("Tape is write-protected.\n");
  34.         exit(0);
  35.       case KEY_BLANKCHK:    /*  Blank Check */
  36.         printf("Tape is blank.  Additional sense is %d\n", aspi_sense[12]);
  37.         exit(0);
  38.       case KEY_MEDIUMERR:   /*  Medium Error */
  39.       case KEY_HARDERROR:   /*  Hardware Error */
  40.       case KEY_ILLGLREQ:    /*  Illegal Request */
  41.       case KEY_UNITATT:     /*  Unit Attention */
  42.       case KEY_VENDSPEC:    /*  Vendor Specific */
  43.       case KEY_COPYABORT:   /*  Copy Abort */
  44.       case KEY_ABORT:       /*  Abort */
  45.       case KEY_EQUAL:       /*  Equal (Search) */
  46.       case KEY_VOLOVRFLW:   /*  Volume Overflow */
  47.       case KEY_MISCOMP:     /*  Miscompare (Search) */
  48.       case KEY_RESERVED:    /*  Reserved */
  49.         printf("Tape error!\n");
  50.         exit(1);
  51.       default:
  52.     printf("Unknown sense error %d (0x%x)\n",
  53.            aspi_sense[2] & 0x0f, aspi_sense[2] & 0x0f);
  54.     exit(1);
  55.     }
  56.   }
  57.   if (aspi_sense[2] & SENSE_ILI)
  58.   {
  59.     printf("Block size is not correct.\n");
  60.     exit(1);
  61.   }
  62. }
  63.  
  64. static void do_cstat(char *x)
  65. {
  66.   printf("Error during %s\n", x);
  67.   check_sense();
  68.   exit(1);
  69. }
  70.  
  71. void tape_open(void)
  72. {
  73.   int nh = aspi_init();
  74.   for (dat=0; dat<64*nh; dat++)
  75.   {
  76.     stat = aspi_device_type(dat);
  77.     if (stat == -1)
  78.       continue;
  79.     if (stat == DTYPE_SEQD)
  80. /*    if (stat == DTYPE_CROM) */
  81.     {
  82.       printf("DAT is scsi(%d,%d,%d)\n",
  83.          ASPI_ID2HOSTAD(dat),
  84.          ASPI_ID2TARGET(dat),
  85.          ASPI_ID2LUN(dat));
  86.       tape_set_blocksize(block_size);
  87.       return;
  88.     }
  89.   }
  90.   printf("No tape drives detected\n");
  91.   exit(0);
  92. }
  93.  
  94. void tape_rewind(int wait)
  95. {
  96.   memset(cdb, 0, 6);
  97.   cdb[0] = 0x01;
  98.   cdb[1] = wait ? 0x00 : 0x01;
  99.   fflush(stdout);
  100.   stat = aspi_exec(dat, 0, 0, ASPI_RW_NODATA, cdb, 6);
  101.   cstat("rewind");
  102. }
  103.  
  104. void tape_set_blocksize(unsigned long new_block_size)
  105.  
  106. {
  107.   unsigned char buffer[12];
  108.   block_size = new_block_size;
  109.   memset(cdb, 0, 6);
  110.   cdb[0] = 0x15;
  111.   cdb[4] = 0x0c;
  112.   memset(buffer, 0, sizeof(buffer));
  113.   buffer[2] = 0x10;
  114.   buffer[3] = 8;
  115.   buffer[9] = (block_size) >> 16;
  116.   buffer[10] = (block_size) >> 8;
  117.   buffer[11] = (block_size);
  118.   stat = aspi_exec(dat, buffer, 12, ASPI_RW_WRITE, cdb, 6);
  119.   cstat("mode select");
  120. }
  121.  
  122. int tape_read(void *buffer) /* 0=OK, 1=LEOT */
  123. {
  124.   unsigned char *sense;
  125.   memset(cdb, 0, 6);
  126.   cdb[0] = 0x08;
  127.   cdb[1] = 0x01;
  128.   cdb[4] = 0x01;
  129.   stat = aspi_exec(dat, buffer, block_size, ASPI_RW_READ, cdb, 6);
  130.   cstat("read from tape");
  131.  
  132.   check_sense();
  133.   if (aspi_sense[2] & SENSE_FILEMRK)
  134.     return 1;
  135.   return 0;
  136. }
  137.  
  138. void tape_write(void *buffer)
  139. {
  140.   memset(cdb, 0, 6);
  141.   cdb[0] = 0x0a;
  142.   cdb[1] = 0x01;
  143.   cdb[4] = 0x01;
  144.   stat = aspi_exec(dat, buffer, block_size, ASPI_RW_WRITE, cdb, 6);
  145.   cstat("write to tape");
  146.  
  147.   check_sense();
  148. }
  149.  
  150. void tape_write_filemark(int count, int isshort)
  151. {
  152.   memset(cdb, 0, 6);
  153.   cdb[0] = 0x10;
  154.   cdb[4] = count;
  155.   cdb[5] = isshort ? 0x80 : 0x00;
  156.   stat = aspi_exec(dat, 0, 0, ASPI_RW_NODATA, cdb, 6);
  157.   cstat("file mark write");
  158. }
  159.  
  160. void tape_close(void)
  161. {
  162.   tape_rewind(0);
  163.   aspi_close();
  164. }
  165.  
  166. char *tape_fmtnum(unsigned long l)
  167. {
  168.   /* 0,000,000,000 */
  169.   static char rv[14];
  170.   char buf[14];
  171.   int i, j;
  172.   sprintf(buf, "%010lu", l);
  173.   for (i=0, j=0; i<13; i++, j++)
  174.   {
  175.     if ((j % 3) == 1)
  176.       rv[i++] = ',';
  177.     rv[i] = buf[j];
  178.   }
  179.   rv[i++] = 0;
  180.   for (i=0; rv[i]; i++)
  181.   {
  182.     if (rv[i] == '0' || rv[i] == ',')
  183.       rv[i] = ' ';
  184.     else
  185.       break;
  186.   }
  187.   return rv;
  188. }
  189.